import { parse } from 'dotenv';
import { readFileSync } from 'fs';
import { number, object, ObjectSchema, string, validate } from 'joi';
import { resolve } from 'path';

type Config = Partial<{
  DB_HOST: string;
  DB_PORT: number;
  DB_NAME: string;
  DB_USER: string;
  DB_PASSWORD: string;
}>;

export class ConfigService {
  private readonly config: Config;

  constructor(filePath: string) {
    const config = parse(
      readFileSync(resolve(__dirname, '../../../env', filePath)),
    );
    this.config = this.validate(config);
  }

  get dbHost() {
    return this.config.DB_HOST;
  }

  get dbPort() {
    return this.config.DB_PORT;
  }

  get dbName() {
    return this.config.DB_NAME;
  }

  get dbUser() {
    return this.config.DB_USER;
  }

  get dbPassword() {
    return this.config.DB_PASSWORD;
  }

  private validate(config: Config): Config {
    const schema: ObjectSchema = object({
      PORT: number().default(3000),
      DB_HOST: string().required(),
      DB_PORT: number().default(3306),
      DB_NAME: string().required(),
      DB_USER: string().required(),
      DB_PASSWORD: string().required(),
    });

    const { error, value } = validate(config, schema);
    if (error) {
      throw new Error(`Config validation error: ${error.message}`);
    }
    return value;
  }
}
